#ifndef TINX_SYSCALL_H
#define TINX_SYSCALL_H

#include <tinx/stat.h>

#define WNOHANG   1
#define WUNTRACED 2

enum SYSCALL
{
    SYS_NR_TEST = 0,
    SYS_NR_EXIT = 1,
    SYS_NR_FORK = 2,
    SYS_NR_READ = 3,
    SYS_NR_WRITE = 4,
    SYS_NR_OPEN = 5,
    SYS_NR_CLOSE = 6,
    SYS_NR_WAITPID = 7,
    SYS_NR_CREAT = 8,
    SYS_NR_LINK = 9,
    SYS_NR_UNLINK = 10,
    SYS_NR_EXECVE = 11,
    SYS_NR_CHDIR = 12,
    SYS_NR_TIME = 13,
    SYS_NR_MKNOD = 14,
    SYS_NR_OLD_STAT = 18,
    SYS_NR_LSEEK = 19,
    SYS_NR_GETPID = 20,
    SYS_NR_MOUNT = 21,
    SYS_NR_UMOUNT = 22,
    SYS_NR_GETUID = 24,
    SYS_NR_OLD_FSTAT = 28,
    SYS_NR_KILL = 37,
    SYS_NR_RENAME = 38,
    SYS_NR_MKDIR = 39,
    SYS_NR_RMDIR = 40,
    SYS_NR_DUP = 41,
    SYS_NR_PIPE = 42,
    SYS_NR_BRK = 45,
    SYS_NR_SIGNAL = 48,
    SYS_NR_IOCTL = 54,
    SYS_NR_FCNTL = 55,
    SYS_NR_SETPGID = 57,
    SYS_NR_UMASK = 60,
    SYS_NR_CHROOT = 61,
    SYS_NR_DUP2 = 63,
    SYS_NR_GETPPID = 64,
    SYS_NR_GETPGRP = 65,
    SYS_NR_SETSID = 66,
    SYS_NR_SIGACTION = 67,
    SYS_NR_SGETMASK = 68,
    SYS_NR_SSETMASK = 69,
    SYS_NR_SYMLINK = 83,
    SYS_NR_READLINK = 85,
    SYS_NR_REBOOT = 88,
    SYS_NR_READDIR = 89,
    SYS_NR_MMAP = 90,
    SYS_NR_MUNMAP = 91,
    SYS_NR_FCHOWN = 95,
    SYS_NR_STAT = 106,
    SYS_NR_FSTAT = 108,
    SYS_NR_MPROTECT = 125,
    SYS_NR_GETDENTS = 141,
    SYS_NR_WRITEV = 146,
    SYS_NR_YIELD = 158,
    SYS_NR_CHOWN = 182,
    SYS_NR_MMAP2 = 192,
    SYS_NR_FCNTL64 = 221,
    SYS_NR_SET_THREAD_AREA = 243,
    SYS_NR_SET_TID_ADDRESS = 258,
    SYS_NR_CLOCK_GETTIME = 265,
    SYS_NR_MKDIRAT = 296,
    SYS_NR_SHUTDOWN = 373,
    SYS_NR_STATX = 383,
    SYS_NR_CLOCK_GETTIME64 = 403,
    SYSCALL_NUM
};

enum mmap_type_t
{
    PROT_NONE = 0,
    PROT_READ = 1,
    PROT_WRITE = 2,
    PROT_EXEC = 4,

    MAP_SHARED = 1,
    MAP_PRIVATE = 2,
    MAP_TYPE = 0xf,
    MAP_FIXED = 0x10,
    MAP_ANONYMOUS = 0x20
};

// 用于测试
int test();

// 创建子进程
pid_t fork();
// 任务主动退出
void exit(int status);
// 等待子进程退出, 返回值存到 status
pid_t waitpid(pid_t pid, int *status, int options);

int execve(char *filename, char *argv[], char *envp[]);

void yield();

// 获得当前时间
time_t time();

// 写文件 count 个字节
int write(fd_t fd, char *buf, int count);
// 读文件 count 个字节
int read(fd_t fd, char *buf, int count);
int ioctl(fd_t fd, int cmd, int arg);

int rename(char *oldname, char *newname);

int mkdir(char *pathname, int mode);
int mkdirat(fd_t fd, char *pathname, int mode);
int rmdir(char *pathname);

int link(char *oldname, char *newname);
int unlink(char *filename);

fd_t open(char *filename, int flags, int mode);
int close(fd_t fd);
fd_t creat(char *filename, int mode);

int readdir(fd_t fd, void *entry, int count);
int getdents(fd_t fd, void *entries, int count);

int lseek(fd_t fd, int offset, int whence);

int chdir(char *pathname);
int chroot(char *pathname);

int stat(char *pathname, stat_t *statbuf);
int fstat(fd_t fd, stat_t *statbuf);

int mknod(char *filename, int mode, int dev);

// 创建管道
int pipe(fd_t pipefd[2]);

int mount(char *devname, char *dirname, int flags);
int umount(char *target);

int symlink(char *oldname, char *newname);
int readlink(char *pathname, char *buf, int size);

int umask(int mask);

int dup2(fd_t oldfd, fd_t newfd);
int dup(fd_t fds);

int brk(u32 newbrk);

void *mmap(void *addr, size_t length, int prot, int flags, int fd, int offset);
int munmap(void *addr, size_t length);

int shutdown();
int reboot();

int set_thread_area(void *desc);
pid_t set_tid_address(int *ptr);

#endif